#!/usr/bin/env node

const fs = require('fs')
const path = require('path')
const { execSync } = require('child_process')

// 性能监控脚本
class PerformanceMonitor {
    constructor() {
        this.outputDir = path.join(process.cwd(), 'performance-reports')
        this.ensureOutputDir()
    }

    ensureOutputDir() {
        if (!fs.existsSync(this.outputDir)) {
            fs.mkdirSync(this.outputDir, { recursive: true })
        }
    }

    // 运行 Lighthouse 审计
    async runLighthouseAudit() {
        console.log('🔍 Running Lighthouse performance audit...')

        const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
        const outputPath = path.join(this.outputDir, `lighthouse-${timestamp}.html`)

        try {
            execSync(`npx lighthouse http://localhost:3000 --output=html --output-path="${outputPath}" --chrome-flags="--headless"`, {
                stdio: 'inherit'
            })

            console.log(`✅ Lighthouse audit completed: ${outputPath}`)
            return outputPath
        } catch (error) {
            console.error('❌ Lighthouse audit failed:', error.message)
            return null
        }
    }

    // 分析构建包大小
    async analyzeBundleSize() {
        console.log('📦 Analyzing bundle size...')

        try {
            // 检查 .next 目录是否存在
            const nextDir = path.join(process.cwd(), '.next')
            if (!fs.existsSync(nextDir)) {
                console.log('⚠️  No build found. Running build first...')
                execSync('npm run build', { stdio: 'inherit' })
            }

            // 生成包分析报告
            const reportPath = path.join(this.outputDir, 'bundle-analysis.json')

            // 分析静态文件大小
            const staticDir = path.join(nextDir, 'static')
            if (fs.existsSync(staticDir)) {
                const analysis = this.analyzeDirectory(staticDir)

                fs.writeFileSync(reportPath, JSON.stringify(analysis, null, 2))
                console.log(`✅ Bundle analysis completed: ${reportPath}`)

                // 输出摘要
                this.printBundleSummary(analysis)

                return reportPath
            } else {
                console.log('⚠️  Static directory not found')
                return null
            }
        } catch (error) {
            console.error('❌ Bundle analysis failed:', error.message)
            return null
        }
    }

    // 分析目录大小
    analyzeDirectory(dirPath) {
        const analysis = {
            totalSize: 0,
            files: [],
            directories: {}
        }

        const items = fs.readdirSync(dirPath)

        for (const item of items) {
            const itemPath = path.join(dirPath, item)
            const stats = fs.statSync(itemPath)

            if (stats.isDirectory()) {
                analysis.directories[item] = this.analyzeDirectory(itemPath)
                analysis.totalSize += analysis.directories[item].totalSize
            } else {
                const fileInfo = {
                    name: item,
                    size: stats.size,
                    sizeFormatted: this.formatBytes(stats.size)
                }
                analysis.files.push(fileInfo)
                analysis.totalSize += stats.size
            }
        }

        // 按大小排序文件
        analysis.files.sort((a, b) => b.size - a.size)

        return analysis
    }

    // 格式化字节数
    formatBytes(bytes) {
        if (bytes === 0) return '0 Bytes'

        const k = 1024
        const sizes = ['Bytes', 'KB', 'MB', 'GB']
        const i = Math.floor(Math.log(bytes) / Math.log(k))

        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    }

    // 打印包大小摘要
    printBundleSummary(analysis) {
        console.log('\n📊 Bundle Size Summary:')
        console.log(`Total Size: ${this.formatBytes(analysis.totalSize)}`)

        console.log('\n🔝 Largest Files:')
        analysis.files.slice(0, 10).forEach((file, index) => {
            console.log(`${index + 1}. ${file.name}: ${file.sizeFormatted}`)
        })

        console.log('\n📁 Directory Sizes:')
        Object.entries(analysis.directories)
            .sort(([, a], [, b]) => b.totalSize - a.totalSize)
            .slice(0, 5)
            .forEach(([name, dir]) => {
                console.log(`${name}: ${this.formatBytes(dir.totalSize)}`)
            })

        // 性能建议
        console.log('\n💡 Performance Recommendations:')

        if (analysis.totalSize > 5 * 1024 * 1024) { // 5MB
            console.log('⚠️  Bundle size is large (>5MB). Consider code splitting.')
        }

        const largeFiles = analysis.files.filter(f => f.size > 1024 * 1024) // 1MB
        if (largeFiles.length > 0) {
            console.log(`⚠️  Found ${largeFiles.length} large files (>1MB). Consider optimization.`)
        }

        const jsFiles = analysis.files.filter(f => f.name.endsWith('.js'))
        const totalJsSize = jsFiles.reduce((sum, f) => sum + f.size, 0)
        if (totalJsSize > 2 * 1024 * 1024) { // 2MB
            console.log('⚠️  JavaScript bundle is large (>2MB). Consider lazy loading.')
        }
    }

    // 检查性能预算
    checkPerformanceBudget() {
        console.log('💰 Checking performance budget...')

        const budget = {
            totalSize: 3 * 1024 * 1024, // 3MB
            jsSize: 1 * 1024 * 1024,    // 1MB
            cssSize: 200 * 1024,        // 200KB
            imageSize: 2 * 1024 * 1024  // 2MB
        }

        const nextDir = path.join(process.cwd(), '.next', 'static')
        if (!fs.existsSync(nextDir)) {
            console.log('⚠️  No build found for budget check')
            return false
        }

        const analysis = this.analyzeDirectory(nextDir)

        let budgetPassed = true

        // 检查总大小
        if (analysis.totalSize > budget.totalSize) {
            console.log(`❌ Total size budget exceeded: ${this.formatBytes(analysis.totalSize)} > ${this.formatBytes(budget.totalSize)}`)
            budgetPassed = false
        } else {
            console.log(`✅ Total size within budget: ${this.formatBytes(analysis.totalSize)}`)
        }

        // 检查 JS 大小
        const jsFiles = analysis.files.filter(f => f.name.endsWith('.js'))
        const totalJsSize = jsFiles.reduce((sum, f) => sum + f.size, 0)

        if (totalJsSize > budget.jsSize) {
            console.log(`❌ JavaScript size budget exceeded: ${this.formatBytes(totalJsSize)} > ${this.formatBytes(budget.jsSize)}`)
            budgetPassed = false
        } else {
            console.log(`✅ JavaScript size within budget: ${this.formatBytes(totalJsSize)}`)
        }

        // 检查 CSS 大小
        const cssFiles = analysis.files.filter(f => f.name.endsWith('.css'))
        const totalCssSize = cssFiles.reduce((sum, f) => sum + f.size, 0)

        if (totalCssSize > budget.cssSize) {
            console.log(`❌ CSS size budget exceeded: ${this.formatBytes(totalCssSize)} > ${this.formatBytes(budget.cssSize)}`)
            budgetPassed = false
        } else {
            console.log(`✅ CSS size within budget: ${this.formatBytes(totalCssSize)}`)
        }

        return budgetPassed
    }

    // 生成性能报告
    async generateReport() {
        console.log('📋 Generating comprehensive performance report...')

        const timestamp = new Date().toISOString()
        const report = {
            timestamp,
            lighthouse: null,
            bundleAnalysis: null,
            budgetCheck: null
        }

        // 运行各项检查
        report.lighthouse = await this.runLighthouseAudit()
        report.bundleAnalysis = await this.analyzeBundleSize()
        report.budgetCheck = this.checkPerformanceBudget()

        // 保存报告
        const reportPath = path.join(this.outputDir, `performance-report-${timestamp.replace(/[:.]/g, '-')}.json`)
        fs.writeFileSync(reportPath, JSON.stringify(report, null, 2))

        console.log(`\n📄 Performance report saved: ${reportPath}`)

        // 输出总结
        console.log('\n🎯 Performance Summary:')
        console.log(`Lighthouse: ${report.lighthouse ? '✅ Completed' : '❌ Failed'}`)
        console.log(`Bundle Analysis: ${report.bundleAnalysis ? '✅ Completed' : '❌ Failed'}`)
        console.log(`Budget Check: ${report.budgetCheck ? '✅ Passed' : '❌ Failed'}`)

        return report
    }
}

// 主函数
async function main() {
    const monitor = new PerformanceMonitor()

    const args = process.argv.slice(2)
    const command = args[0] || 'report'

    switch (command) {
        case 'lighthouse':
            await monitor.runLighthouseAudit()
            break
        case 'bundle':
            await monitor.analyzeBundleSize()
            break
        case 'budget':
            monitor.checkPerformanceBudget()
            break
        case 'report':
        default:
            await monitor.generateReport()
            break
    }
}

// 运行脚本
if (require.main === module) {
    main().catch(error => {
        console.error('❌ Performance monitoring failed:', error)
        process.exit(1)
    })
}

module.exports = PerformanceMonitor